iT邦幫忙

2023 iThome 鐵人賽

DAY 9
1
自我挑戰組

複習 JavaScript 核心概念系列 第 9 篇

[Day 09] 不可不知的事件循環(Event Loop)

  • 分享至 

  • xImage
  •  

昨天稍微講了 同步 和 非同步 ,而實際上 JavaScript 是怎麼做到非同步的,那就是今天的主體:事件循環(Event Loop)。在這之前,要先來介紹整個瀏覽器環境中除了 JavaScript 本身外的兩大組成要素,分別是 Web APIs 和 Callback Queue(回調佇列)。

Web APIs

我們在使用 JavaScript 的非同步程式碼時,其實是依靠一個稱為Web APIs的酷東西,它是瀏覽器提供的一系列非同步操作Api,用於處理網絡請求、計時器、DOM 操作等。當使用 Web APIs(例如 setTimeout、fetch、XMLHttpRequest 等)執行非同步操作時,這些操作會在背景中運行,而不會阻塞 JavaScript 的執行;而當操作完成後,會將對應的 callback function(回調函式) 放入 Callback Queue。

Callback Queue(回調佇列中的)

Callback Queue,或稱Task Queue,是一個先進先出(FIFO,先進先出)的資料結構,這裡存放來自 Web APIs 完成非同步操作後回傳的callback(回調函式)。

這些放在佇列中的callback會一直等待,直到適當的時機點被移出佇列。
這個時機點為 JavaScript 的的呼叫堆疊(call stack)為空的時候(即當所有同步操作完成後),Callback Queue中 callback 會一個一個依序被移出佇列並放入JavaScript的呼叫堆疊(call stack)中執行。


只看文字或許不太明白,我們直接來看圖。 (圖片來源)

上圖是整個瀏覽器環境中整體的運作流程,可以明顯看到三大區塊:JS引擎、Web APIs、Callback Queue。
先簡單分析上圖,先看左上,JavaScript 堆疊(Call Stack)最頂端的 setTimeout() 是非同步,因此它會被交給 WebApis 去處理,而 JS引擎 則會繼續執行 showText() ,就這樣一直執行堆疊中剩下的內容。

而另一邊當 WebApis 將 setTimeout() 處理完畢時,它會將「setTimeout() 對應的callback」放入 Callback Queue,而不會被 JavaScript 立即執行。

回到JavaScript 堆疊(Call Stack)這邊,當呼叫堆疊內都執行完畢(堆疊為空時),就會從 Callback Queue 依序取出 callback 並執行。

另外,關於上圖 Callback Queue 中的 Macrotask 與 MicroTask ,是兩種非同步操作的類型,它們有不同的執行順序和優先級。這留到明天再談。

以下是以動圖的方式呈現的範例。 (圖片來源)

關於以上動圖的畫面,其實是一個叫做 Loupe 的網站,這個視覺化小工具,可以幫助我們了解 JavaScript 的Call Stack(呼叫堆疊)、Web Apis、Callback Queue(回調佇列)如何互動的,讓我們可以更清楚 事件循環(Event Loop) 的運作過程。

另外 Loupe 網站中提到的影片「所以說event loop到底是什麼玩意兒?」中詳細介紹了 Event Loop 的運作
原理,更是非常值得一看。

那麼今天就到這邊,明天見~


上一篇
[Day 08] JavaScript 中的同步(synchronous)和非同步(asynchronous)
下一篇
[Day 10] 非同步任務的兩種類型:Macrotask 與 MicroTask
系列文
複習 JavaScript 核心概念 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言